//
//  YDThreadController.m
//  YDBASE
//
//  Created by rowena on 2019/5/8.
//  Copyright © 2019 wuyezhiguhun. All rights reserved.
//

#import "YDThreadController.h"
#import "YDGCDThread.h"
#import "YDThread.h"
#import "YDOperation.h"

@interface YDThreadController ()

@property (nonatomic, assign) NSInteger ticketSurplusCount;

@property (nonatomic, strong) NSThread *ticketSaleWindow1;
@property (nonatomic, strong) NSThread *ticketSaleWindow2;

@property (nonatomic, strong) NSLock *theLock;

@end

@implementation YDThreadController

- (void)viewDidLoad {
    [super viewDidLoad];

    
//    [self setAllThread];
    
//    [self initTicketStatusSave];
    
//    [self initTicketStatusSaveThread];
    
//    [self initTicketStatusSaveLock];
    
    [self testOperation];
    
}


#pragma mark ==== YDPeration ====
/**
 * YDOperation
 */
- (void)testOperation {
    YDOperation *operation = [[YDOperation alloc] init];
    
//    /**
//     * NSBlockOperation
//     */
//    [operation blockOperation1];

    /**
     * NSBlockOperation队列
     */
    [operation blockOperationWithExecutionList];

//    /**
//     * 使用NSOperationQueue来创建任务
//     */
//    [operation operationQueueWithOperationList];
//
//    /**
//     * 队列的使用----依赖执行任务
//     */
//    [operation depenceyOperation];
//
//    /**
//     * 队列的使用---设置最大并发数
//     */
//    [operation maxConcurrentOperationCount];

}

/**
 * 初始化火车票数量、卖票窗口(线程安全)、并开始卖票
 */
- (void)initTicketStatusSaveLock {
    // 1. 设置剩余火车票为 50
    self.ticketSurplusCount = 50;
    
    self.theLock = [[NSLock alloc] init];
    
    // 2. 设置北京火车票售卖窗口的线程
    self.ticketSaleWindow1 = [[NSThread alloc]initWithTarget:self selector:@selector(saleTicketSafeThread) object:nil];
    self.ticketSaleWindow1.name = @":<- 北京火车票售票窗口 ->:";
    
    // 3. 设置上海火车票售卖窗口的线程
    self.ticketSaleWindow2 = [[NSThread alloc]initWithTarget:self selector:@selector(saleTicketSafeThread) object:nil];
    self.ticketSaleWindow2.name = @":<- 上海火车票售票窗口 ->:";
    
    // 4. 开始售卖火车票
    [self.ticketSaleWindow1 start];
    [self.ticketSaleWindow2 start];
    
}

/**
 * 售卖火车票(线程安全)
 */
- (void)saleTicketSafeLock {
    while (1) {
        //互斥锁 -- 保证锁内的代码在同一时间内只有一个线程在执行
        // 互斥锁
        [self.theLock lock];
        //如果还有票，继续售卖
        if (self.ticketSurplusCount > 0) {
            self.ticketSurplusCount --;
            NSLog(@"wuyezhiguhun ->: %@", [NSString stringWithFormat:@"剩余票数：%ld 窗口：%@", self.ticketSurplusCount, [NSThread currentThread].name]);
            [NSThread sleepForTimeInterval:0.2];
        }
        //如果已卖完，关闭售票窗口
        else {
            [self.theLock unlock];
            NSLog(@"wuyezhiguhun ->: 所有火车票均已售完");
            break;
        }
        [self.theLock unlock];
    }
}


/**
 * 初始化火车票数量、卖票窗口(线程安全)、并开始卖票
 */
- (void)initTicketStatusSaveThread {
    // 1. 设置剩余火车票为 50
    self.ticketSurplusCount = 50;
    
    // 2. 设置北京火车票售卖窗口的线程
    [YDThread yd_NewThreadWithTarget:self selector:@selector(saleTicketSafeThread) service:NSQualityOfServiceBackground name:@" :北京火车票售票窗口 ->:" object:nil open:YES];
    
//    self.ticketSaleWindow1 = [[NSThread alloc]initWithTarget:self selector:@selector(saleTicketSafeThread) object:nil];
//    self.ticketSaleWindow1.name = @"北京火车票售票窗口";
    
    // 3. 设置上海火车票售卖窗口的线程
    [YDThread yd_NewThreadWithTarget:self selector:@selector(saleTicketSafeThread) service:NSQualityOfServiceBackground name:@" :上海火车票售票窗口 ->:" object:nil open:YES];
    
//    self.ticketSaleWindow2 = [[NSThread alloc]initWithTarget:self selector:@selector(saleTicketSafeThread) object:nil];
//    self.ticketSaleWindow2.name = @"上海火车票售票窗口";
    
    // 4. 开始售卖火车票
//    [self.ticketSaleWindow1 start];
//    [self.ticketSaleWindow2 start];
    
}

/**
 * 售卖火车票(线程安全)
 */
- (void)saleTicketSafeThread {
    while (1) {
        
        [YDThread yd_SynchronizedBack:^{
            //如果还有票，继续售卖
            if (self.ticketSurplusCount > 0) {
                self.ticketSurplusCount --;
                NSLog(@"wuyezhiguhun ->: %@", [NSString stringWithFormat:@"剩余票数：%ld 窗口：%@", self.ticketSurplusCount, [NSThread currentThread].name]);
                [NSThread sleepForTimeInterval:0.2];
            }
        }];
        if (self.ticketSurplusCount <= 0) {
            NSLog(@"wuyezhiguhun ->: 所有火车票均已售完");
            break;
        }
        
//        //互斥锁 -- 保证锁内的代码在同一时间内只有一个线程在执行
//        // 互斥锁
//        @synchronized (self) {
//            //如果还有票，继续售卖
//            if (self.ticketSurplusCount > 0) {
//                self.ticketSurplusCount --;
//                NSLog(@"wuyezhiguhun ->: %@", [NSString stringWithFormat:@"剩余票数：%ld 窗口：%@", self.ticketSurplusCount, [NSThread currentThread].name]);
//                [NSThread sleepForTimeInterval:0.2];
//            }
//            //如果已卖完，关闭售票窗口
//            else {
//                NSLog(@"wuyezhiguhun ->: 所有火车票均已售完");
//                break;
//            }
//        }
    }
}

/**
 * 线程安全：使用 semaphore 加锁
 * 初始化火车票数量、卖票窗口(线程安全)、并开始卖票
 */
- (void)initTicketStatusSave {
    
    self.ticketSurplusCount = 50;
    
    // queue1 代表北京火车票售卖窗口
    dispatch_queue_t queue1 = dispatch_queue_create("net.bujige.testQueue1", DISPATCH_QUEUE_SERIAL);
    // queue2 代表上海火车票售卖窗口
    dispatch_queue_t queue2 = dispatch_queue_create("net.bujige.testQueue2", DISPATCH_QUEUE_SERIAL);
    
    __weak typeof(self) weakSelf = self;
    
    [YDGCDThread yd_AsyncQueue:queue1 back:^{
        [weakSelf saleTicketSafe];
    }];
    
    [YDGCDThread yd_AsyncQueue:queue2 back:^{
        [weakSelf saleTicketSafe1];
    }];
    
}

/**
 * 售卖火车票(线程安全)
 */
- (void)saleTicketSafe {
    while (1) {
        
        [[YDGCDThread sharedThread] yd_LockBack:^{
            if (self.ticketSurplusCount > 0) {  //如果还有票，继续售卖
                self.ticketSurplusCount--;
                NSLog(@"wuyezhiguhun ->: %@", [NSString stringWithFormat:@"剩余票数：%d 窗口：%@", self.ticketSurplusCount, [NSThread currentThread]]);
                [NSThread sleepForTimeInterval:0.2];
            }
        }];
        
        if (self.ticketSurplusCount <= 0) {
            NSLog(@"wuyezhiguhun ->: 所有火车票均已售完");
            break;
        }
    }
}

/**
 * 售卖火车票(线程安全)
 */
- (void)saleTicketSafe1 {
    while (1) {
        
        [[YDGCDThread sharedThread] yd_Lock];
        if (self.ticketSurplusCount > 0) {  //如果还有票，继续售卖
            self.ticketSurplusCount--;
            NSLog(@"wuyezhiguhun ->: %@", [NSString stringWithFormat:@"剩余票数：%d 窗口：%@", self.ticketSurplusCount, [NSThread currentThread]]);
            [NSThread sleepForTimeInterval:0.2];
        } else { //如果已卖完，关闭售票窗口
            NSLog(@"wuyezhiguhun ->: 所有火车票均已售完");
            [[YDGCDThread sharedThread] yd_Unlock];
            break;
        }
        [[YDGCDThread sharedThread] yd_Unlock];

    }
}

//设置多线程
- (void)setAllThread {
    dispatch_queue_t queue = dispatch_queue_create("weixin.wuyezhiguhun.queue", DISPATCH_QUEUE_CONCURRENT);
    
    /** 同步执行 主线程 类方法 */
    [YDGCDThread yd_SyncQueue:queue back:^{
        //打印当前线程
        NSLog(@":<- wuyezhiguhun ->: SyncQueue ->: DISPATCH_QUEUE_SERIAL ->: currentThread ->: %@", [NSThread currentThread]);
    }];
    
    /** 异步执行 主线程 类方法 */
    [YDGCDThread yd_AsyncMainQueueBack:^{
        //打印当前线程
        NSLog(@":<- wuyezhiguhun ->: AsyncMainQueueBack ->: currentThread ->: %@", [NSThread currentThread]);
    }];
    
    /**  异步执行 主线程 类方法 */
    [YDGCDThread yd_AsyncQueue:queue back:^{
        //打印当前线程
        NSLog(@":<- wuyezhiguhun ->: AsyncQueue ->: DISPATCH_QUEUE_SERIAL ->:2 ->: currentThread ->: %@", [NSThread currentThread]);
    }];
    [YDGCDThread yd_AsyncQueue:queue back:^{
        //打印当前线程
        NSLog(@":<- wuyezhiguhun ->: AsyncQueue ->: DISPATCH_QUEUE_SERIAL ->:3 ->: currentThread ->: %@", [NSThread currentThread]);
    }];
    [YDGCDThread yd_AsyncQueue:queue back:^{
        //打印当前线程
        NSLog(@":<- wuyezhiguhun ->: AsyncQueue ->: DISPATCH_QUEUE_SERIAL ->:4 ->: currentThread ->: %@", [NSThread currentThread]);
    }];
    
    /** 同步执行 主线程 对象方法 */
    [[YDGCDThread sharedThread] yd_SyncQueue:queue back:^{
        //打印当前线程
        NSLog(@":<- wuyezhiguhun ->: ****** ->: SyncMainQueueBack ->: currentThread ->: %@", [NSThread currentThread]);
    }];
    
    /** 异步执行 主线程 对象方法 */
    [[YDGCDThread sharedThread] yd_AsyncMainQueueBack:^{
        //打印当前线程
        NSLog(@":<- wuyezhiguhun ->: ****** ->: AsyncMainQueueBack ->: currentThread ->: %@", [NSThread currentThread]);
    }];
    
    /** 异步执行 主线程 对象方法 */
    [[YDGCDThread sharedThread] yd_AsyncQueue:queue back:^{
        //打印当前线程
        NSLog(@":<- wuyezhiguhun ->: ****** ->: AsyncQueue ->: DISPATCH_QUEUE_SERIAL ->: currentThread ->: %@", [NSThread currentThread]);
    }];
    
    /** 同步执行 串行 对象方法 */
    [[YDGCDThread sharedThread] yd_SyncSerialQueueBack:^{
        //打印当前线程
        NSLog(@":<- wuyezhiguhun ->: ****** ->: SyncSerialQueueBack ->: currentThread ->: %@", [NSThread currentThread]);
    }];
    /**
     * 异步执行 串行 对象方法
     * @pram back 回调
     */
    [[YDGCDThread sharedThread] yd_AsyncSerialQueueBack:^{
        //打印当前线程
        NSLog(@":<- wuyezhiguhun ->: ****** ->: AsyncSerialQueueBack ->: currentThread ->: %@", [NSThread currentThread]);
    }];
    
    /**  同步执行 并行 对象方法 */
    [[YDGCDThread sharedThread] yd_SyncConcurrentQueueBack:^{
        //打印当前线程
        NSLog(@":<- wuyezhiguhun ->: ****** ->: SyncConcurrentQueueBack ->: currentThread ->: %@", [NSThread currentThread]);
    }];
    
    /** 异步执行 并行 对象方法 */
    [[YDGCDThread sharedThread] yd_AsyncConcurrentQueueBack:^{
        //打印当前线程
        NSLog(@":<- wuyezhiguhun ->: ****** ->: AsyncConcurrentQueueBack ->: currentThread ->: %@", [NSThread currentThread]);
    }];
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end
